package com.zmj.sy.mom.srv.aps.controller;

import cn.hutool.core.collection.CollUtil;
import com.zmj.sy.mom.srv.aps.bean.entity.base.BaseEntity;
import com.zmj.sy.mom.srv.aps.bean.entity.order.ApsBatch;
import com.zmj.sy.mom.srv.aps.bean.entity.order.ApsOrder;
import com.zmj.sy.mom.srv.aps.bean.entity.order.Order;
import com.zmj.sy.mom.srv.aps.bean.entity.order.OrderBom;
import com.zmj.sy.mom.srv.aps.bean.vo.apsorder.ApsOrderScheduleReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.base.*;
import com.zmj.sy.mom.srv.aps.bean.vo.customer.CustomerAddReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.importframe.ImportFrameOrderErpAppendReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.importframe.ImportFrameOrderMbdReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.importframe.ImportFrameOrderPubReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.order.*;
import com.zmj.sy.mom.srv.aps.bean.vo.processchainitem.OrderPhaseEditReqVo;
import com.zmj.sy.mom.srv.aps.config.StrategyConfig;
import com.zmj.sy.mom.srv.aps.mapper.OrderBomMapper;
import com.zmj.sy.mom.srv.aps.service.*;
import com.zmj.sy.mom.srv.aps.utils.*;
import com.zmj.sy.mom.srv.aps.utils.order.ExternalOrder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.*;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Api(tags = "订单")
@RestController
@RequestMapping("/order")
public class OrderController {

    private final StrategyConfig strategyConfig;

    private final OrderService orderService;

    private final CustomerService customerService;

    private final ApsOrderService apsOrderService;

    private final ApsBatchService apsBatchService;

    private final OrderSchedulingService orderSchedulingService;

    private final WmsService wmsService;
    private final StringRedisTemplate stringRedisTemplate;
    private final PlanService planService;
    private final NestService nestService;
    private final OrderBomMapper orderBomMapper;
    private final QmsService qmsService;
    private final OrderMaterialBorrowService orderMaterialBorrowService;

    @Value("${rollback.flag:false}")
    private boolean rollBackFlag;

    @ApiOperation("2.1.1 外部订单-选择框")
    @GetMapping("/externalSelect")
    public BaseSelectResVo externalSelect(OrderExternalSelectReqVo reqVo) {
        ExternalOrder externalOrder = strategyConfig.getExternalOrder(reqVo.getSourceCode());
        return externalOrder.externalSelect(reqVo);
    }

    @ApiOperation("2.1.2 外部订单-导入")
    @PostMapping("/externalImport")
    public BaseResVo externalImport(@RequestBody OrderExternalImportReqVo reqVo) {
        ExternalOrder externalOrder = strategyConfig.getExternalOrder(reqVo.getSourceCode());
        externalOrder.externalImport(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("2.1.3 外部订单-列表")
    @GetMapping("/externalList")
    public BasePageResVo<OrderExternalListResVo> externalList(OrderExternalListReqVo reqVo) {
        ExternalOrder externalOrder = strategyConfig.getExternalOrder(reqVo.getSourceCode());
        return externalOrder.externalList(reqVo);
    }

    @ApiOperation("2.1.4 外部订单-Bom")
    @GetMapping("/externalBom")
    public BaseListResVo<OrderExternalBomResVo> externalBom(OrderExternalBomReqVo reqVo) {
        ExternalOrder externalOrder = strategyConfig.getExternalOrder(reqVo.getSourceCode());
        return externalOrder.externalBom(reqVo);
    }

    @ApiOperation("2.1.4 外部订单-Bom删除")
    @PostMapping("/externalBomDel")
    public BaseResVo externalBomDel(@RequestBody OrderExternalBomDelReqVo reqVo) {
//        ExternalOrder externalOrder = strategyConfig.getExternalOrder(reqVo.getSourceCode());
//        externalOrder.externalBomDel(reqVo);
        orderService.externalBomDel(reqVo.getId());
        return BaseResVo.ok();
    }

    @ApiOperation("2.1.5 订单管理-新增节点")
    @PostMapping("/bomAdd")
    public BaseResVo bomAdd(@RequestBody OrderBomAddReqVo reqVo) {
        orderService.bomAdd(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("2.1.5 订单管理-新增工序")
    @PostMapping("/phaseAdd")
    public BaseResVo phaseAdd(@RequestBody OrderPhaseAddReqVo reqVo) {
        orderService.phaseAdd(reqVo);
        return BaseResVo.ok();
    }


    @ApiOperation("插入工序-马凯")
    @PostMapping("/phaseAddMk")
    public BaseResVo phaseAddMk(@RequestBody OrderPhaseAddMkReqVo reqVo) {
        orderService.phaseAddMk(reqVo);
        return BaseResVo.ok();
    }


    @ApiOperation("2.1.5 订单管理-编辑工序")
    @PostMapping("/phaseEdit")
    public BaseResVo phaseEdit(@RequestBody OrderPhaseEditReqVo reqVo) {
        orderService.phaseEdit(reqVo);
        return BaseResVo.ok();
    }


    @ApiOperation("2.1.5 订单管理-删除工序")
    @PostMapping("/phaseDelete")
    public BaseResVo phaseDelete(@RequestBody BaseIdReqVo reqVo) {
        orderService.phaseDelete(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("2.1.5 订单管理-上移")
    @PostMapping("/phaseUp")
    public BaseResVo phaseUp(@RequestBody BaseIdReqVo reqVo) {
        orderService.phaseUp(reqVo);
        return BaseResVo.ok();
    }


    @ApiOperation("2.1.5 订单管理-下移")
    @PostMapping("/phaseDown")
    public BaseResVo phaseDown(@RequestBody BaseIdReqVo reqVo) {
        orderService.phaseDown(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("2.1.5 外部订单-同步子节点列表")
    @GetMapping("/externalDetail")
    public BaseListResVo<OrderExternalDetailResVo> externalDetail(OrderExternalDetailReqVo reqVo) {
        ExternalOrder externalOrder = strategyConfig.getExternalOrder(reqVo.getSourceCode());
        return externalOrder.externalDetail(reqVo);
    }

    @ApiOperation("2.1.6 外部订单-同步")
    @PostMapping("/externalSync")
    public BaseResVo externalSync(@RequestBody OrderExternalSyncReqVo reqVo) {
        ExternalOrder externalOrder = strategyConfig.getExternalOrder(reqVo.getSourceCode());
        externalOrder.externalSync(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("2.2.1 生产订单管理-订单列表")
    @GetMapping("/list")
    public BasePageResVo<OrderListResVo> list(OrderListReqVo reqVo) {
        return orderService.list(reqVo);
    }
    @ApiOperation("2.2.8 策划订单管理")
    @GetMapping("/planList")
    public BasePageResVo<OrderListResVo> planList(PlanOrderListReqVo reqVo) {
        return orderService.planList(reqVo);
    }
    @ApiOperation("2.2.2 获取订单编号列表")
    @GetMapping("/listCode")
    public BaseListResVo<String> listCode(OrderListReqVo reqVo) {
        return orderService.listCode(reqVo);
    }
    @ApiOperation("预排产新增包次推送详情和零件推送详情")
    @GetMapping("/preOrderList")
    public PageUtils<PreOrderListResVo> preOrderList(OrderListReqVo reqVo) {
        BasePageResVo<OrderListResVo> page1 = orderService.list(reqVo);
        List<PreOrderListResVo> list = orderService.preOrderList(page1);
        return new PageUtils<>(reqVo.getPage(), reqVo.getSize(), list);
    }

    @ApiOperation("2.2.2 生产订单管理-设置客户权重")
    @PostMapping("/customerAdd")
    public BaseResVo customerAdd(@RequestBody CustomerAddReqVo reqVo) {
        customerService.add(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("2.2.3 生产订单管理-修改订单")
    @PostMapping("/edit")
    public BaseResVo edit(@RequestBody OrderEditReqVo reqVo) {
        orderService.edit(reqVo);
        return BaseResVo.ok();
    }
    @ApiOperation("2.2.3 生产订单管理-修改订单")
    @PostMapping("/editMbd")
    public BaseResVo editMbd(@RequestBody OrderEditMbdReqVo reqVo) {
        orderService.editMbd(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("2.2.4 生产订单管理-订单BOM-左侧树")
    @GetMapping("/bom")
    public BaseListResVo<OrderBomResVo> bom(BaseIdReqVo reqVo) {
        return orderService.bom(reqVo);

    }

    @ApiOperation("2.2.5 生产订单管理-订单BOM-右侧列表")
    @GetMapping("/bomList")
    public BaseListResVo<OrderBomListResVo> bomList(BaseIdReqVo reqVo) {
        return orderService.bomList(reqVo);
    }

    @ApiOperation("2.2.5 生产订单管理-订单BOM-左侧树")
    @GetMapping("/bomPhase")
    public BaseListResVo<OrderBomPhaseResVo> bomPhase(BaseIdReqVo reqVo) {
        return orderService.bomPhase(reqVo);

    }

    @ApiOperation("2.2.6 生产订单管理-订单列表")
    @GetMapping("/listMbd")
    public BasePageResVo<OrderListResVo> listMbd(OrderListReqVo reqVo) {
        return orderService.listMbd(reqVo);
    }

    @ApiOperation("发布策划")
    @PostMapping("/mbdPub")
    public BaseResVo mbdPub(@RequestBody PlandOrderAddReqVo reqVo) {
        orderService.mbdPub(reqVo);
        return BaseResVo.ok();
    }
    @ApiOperation("发布策划")
    @PostMapping("/updatePlanedSeq")
    public BaseResVo updatePlanedSeq(@RequestBody OrderUpdatePlaneSeqReqVo reqVo) {
        orderService.updatePlanedSeq(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("已排产总订单")
    @GetMapping("/schedulingList")
    public BasePageResVo<OrderSchedulingListResVo> schedulingList(OrderSchedulingListReqVo reqVo) {
        return orderService.schedulingList(reqVo);
    }

    @ApiOperation("移动待排产顺序")
    @PostMapping("/moveSeq")
    public BaseResVo moveSeq(@RequestBody BaseIdsReqVo reqVo) {
        orderService.moveSeq(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("排产")
    @PostMapping("/scheduling ")
    public BaseResVo scheduling(@RequestBody OrderSchedulingReqVo reqVo){

        orderSchedulingService.scheduling(reqVo);

        return BaseResVo.ok();
    }



    @ApiOperation("开始排产")
    @PostMapping("/schedule")
    public BaseResVo schedule(@RequestBody OrderScheduleReqVo reqVo) {
        if (reqVo.getPreview() == null) {
            reqVo.setPreview(false);
        }

        List<ApsOrder> schedule = orderService.schedule(reqVo, null);

        ApsOrderScheduleReqVo reqVo1 = new ApsOrderScheduleReqVo();
        reqVo1.setIds(schedule.stream().map(BaseEntity::getId).collect(Collectors.toList()));
        reqVo1.setSchedulingRule(reqVo.getSchedulingRule());
        reqVo1.setStartDateTime(LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.of(0, 0, 0)));
        reqVo1.setPreview(reqVo.getPreview());
        reqVo1.setBottleneckPhaseCode(WorkshopProp.BOTTLENECK_PHASE_CODE);
        reqVo1.setCacheOrder(reqVo.getCacheOrder());
        try {

            // 锁定
            apsOrderService.lock(reqVo1);

            // 清理订单
            apsOrderService.clear(reqVo1.getIds());

            // 排产
            apsOrderService.schedule(reqVo1, null);

            // 如果抛异常，则给未排产的解锁
            apsOrderService.unlock(reqVo1, 5);

        } catch (Exception e) {

            // 如果抛异常，则给未排产的解锁
            apsOrderService.unlock(reqVo1, 3);

            // 清理订单
            apsOrderService.clear(reqVo1.getIds());

            log.error(e.getMessage(), e);

            throw e;
        }
        return BaseResVo.ok();
    }


    @ApiOperation("开始排产-MBD")
    @PostMapping("/scheduleMbdOld")
    public BaseResVo scheduleMbdOld(@RequestBody OrderScheduleReqVo reqVo) {
        reqVo.setPreview(true);
        reqVo.setSchedulingRule(1);

        List<ApsOrder> schedule = orderService.selectChildren(reqVo);

        ApsOrderScheduleReqVo reqVo1 = new ApsOrderScheduleReqVo();
        reqVo1.setIds(schedule.stream().map(BaseEntity::getId).collect(Collectors.toList()));
        reqVo1.setSchedulingRule(reqVo.getSchedulingRule());
        reqVo1.setStartDateTime(LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.of(0, 0, 0)));
        reqVo1.setPreview(reqVo.getPreview());
        try {

            // 锁定
            apsOrderService.lock(reqVo1);

            // 清理订单
            apsOrderService.clear(reqVo1.getIds());

            // 排产
            ApsBatch batch = apsOrderService.schedule(reqVo1, null);

            // 如果抛异常，则给未排产的解锁
            apsOrderService.unlock(reqVo1, 5);

            orderService.publish(batch);

        } catch (Exception e) {


            // 如果抛异常，则给未排产的解锁
            apsOrderService.unlock(reqVo1, 3);
            // 清理订单
            apsOrderService.clear(reqVo1.getIds());

            log.error(e.getMessage(), e);
            throw e;
        }

        return BaseResVo.ok();
    }

    @ApiOperation("MBD预排产-新")
    @PostMapping("/scheduleMbd")
    public BaseResVo scheduleMbd(OrderScheduleReqVo reqVo) {

        // 检查redis是否有锁定状态，如果有则提示，并且不排产
        ValueOperations<String, String> valOperation = stringRedisTemplate.opsForValue();
        String lockFlag = valOperation.get(ApsConstant.APS_SCHEDULING_LOCK);
        if (StringUtils.hasText(lockFlag)) {
            throw SyExceptionUtils.e("{} 等订单排产中!", lockFlag);
        }

        try {
            if(reqVo.getSchedulingRule() == null){
                reqVo.setSchedulingRule(2);
            }
            planService.schedulingMbd(reqVo);
        } finally {
            planService.unlockMbd(reqVo);
        }

        return BaseResVo.ok();
    }

    @ApiOperation("排产发布")
    @PostMapping("/publish")
    public BaseResVo publish() {
        List<ApsOrder> publish = orderService.publish();

        String errorMsg = "";

        List<Integer> orderIdList = publish.stream().map(ApsOrder::getOrderId).distinct().collect(Collectors.toList());
        // TODO 部署43环境需要注释掉
        for (Integer orderId : orderIdList) {
            // 下发外购件领料单到立体库
            wmsService.partProcurement(orderId, 0);
            // 下发粉末领料单到备件库
            wmsService.powderOutReceiveAps(orderId);
        }

        // TODO 部署43环境取消注释
        /*try {
            BaseIdsReqVo vo = new BaseIdsReqVo();
            vo.setIds(orderIdList);
            nestService.pushPlanAdd(vo);
        } catch (Exception e) {
            errorMsg = e.getMessage() + "__";
        }*/

        // 判断是否有符合规则的施工号，放入零件池
//        orderMaterialBorrowService.check(orderIdList);

        try {
            List<OrderBom> orderBomList = orderBomMapper.lambdaQuery().in(OrderBom::getOrderId, orderIdList).isNull(OrderBom::getPid).list();
            for (OrderBom bom : orderBomList) {
                qmsService.pushOrderMaterial2QMS(bom.getId());
            }
        } catch (Exception e) {
            errorMsg = e.getMessage() + "__" + errorMsg;
        }
        return BaseResVo.ok(errorMsg);
    }

    @ApiOperation("发布回退")
    @PostMapping("/pubFallback")
    public BaseResVo pubFallback(BaseIdsReqVo reqVo) {
//        if(!rollBackFlag){
//            throw SyExceptionUtils.e("目前无法解锁生产订单");
//        }

        orderService.pubFallback(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("已发布总订单")
    @GetMapping("/pubList")
    public BasePageResVo<OrderPubListResVo> erpPubList(OrderPubListReqVo reqVo) {
        return orderService.erpPubList(reqVo);
    }

    @ApiOperation("进行中的总订单")
    @GetMapping("/doingList")
    public BaseSelectResVo doingList() {
        return orderService.doingList();
    }

    @ApiOperation("锁定生产订单")
    @PostMapping("/lock")
    public BaseResVo lock(BaseIdsReqVo reqVo) {
        orderService.lock(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("解锁生产订单")
    @PostMapping("/unlock")
    public BaseResVo unlock(BaseIdsReqVo reqVo) {
//        if(!rollBackFlag){
//            throw SyExceptionUtils.e("目前无法解锁生产订单");
//        }

        orderService.unlock(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("移出排产")
    @PostMapping("/unMoveAps")
    public BaseResVo unMoveAps(BaseIdReqVo reqVo) {
        orderService.unMoveAps(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("总工作组负荷")
    @GetMapping("/groupLoads")
    public OrderGroupLoadsResVo groupLoads(OrderGroupLoadsReqVo reqVo) {
        return orderService.groupLoads(reqVo);
    }

    @ApiOperation("总工作组负荷列表")
    @GetMapping("/groupLoadsList")
    public BaseListResVo<OrderGroupLoadsListResVo> groupLoadsList(OrderGroupLoadsListReqVo reqVo) {
        return orderService.groupLoadsList(reqVo);
    }

    @ApiOperation("总工作组负荷详情")
    @GetMapping("/groupLoadsDetail")
    public BaseListResVo<OrderGroupLoadsDetailResVo> groupLoadsDetail(OrderGroupLoadsDetailReqVo reqVo) {
        return orderService.groupLoadsDetail(reqVo);
    }

    @ApiOperation("总订单甘特图")
    @GetMapping("/prodGantt")
    public BaseListResVo<OrderProdGanttResVo> prodGantt(OrderProdGanttReqVo reqVo) {
        return orderService.prodGantt(reqVo);
    }

    @ApiOperation("插入批次")
    @PostMapping("/afterSchedule")
    public BaseResVo afterSchedule(@RequestBody OrderAfterScheduleReqVo reqVo) {
        List<ApsBatch> apsBatchList = orderService.afterSchedule(reqVo);
        apsOrderService.afterScheduleClear(apsBatchList);

        ApsBatch first = apsBatchService.getNoPubLast();

        apsBatchList.add(0, first);


        for (int i = 0; i < apsBatchList.size(); i++) {
            ApsBatch apsBatch = apsBatchList.get(i);

            OrderScheduleReqVo rrr = new OrderScheduleReqVo();
            rrr.setSchedulingRule(apsBatch.getSchedulingRule());
            List<ApsOrder> schedule = orderService.schedule(rrr, apsBatch);


            ApsOrderScheduleReqVo reqVo1 = new ApsOrderScheduleReqVo();
            reqVo1.setIds(schedule.stream().map(BaseEntity::getId).collect(Collectors.toList()));
            reqVo1.setSchedulingRule(rrr.getSchedulingRule());
            reqVo1.setStartDateTime(LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.of(0, 0, 0)));
            try {


                // 锁定
                apsOrderService.lock(reqVo1);

                // 清理订单
                apsOrderService.clear(reqVo1.getIds());

                // 排产
                apsOrderService.schedule(reqVo1, apsBatch);

                // 如果抛异常，则给未排产的解锁
                apsOrderService.unlock(reqVo1, 5);

            } catch (Exception e) {


                // 如果抛异常，则给未排产的解锁
                apsOrderService.unlock(reqVo1, 3);
                // 清理订单
                apsOrderService.clear(reqVo1.getIds());

                log.error(e.getMessage(), e);
                throw e;
            }

        }


        return BaseResVo.ok();

    }

    @ApiOperation("移入批次")
    @PostMapping("/moveSchedule")
    public BaseResVo moveSchedule(@RequestBody OrderMoveScheduleReqVo reqVo) {
        // 拿出本条
        ApsBatch source = apsBatchService.getById(reqVo.getSourceBatchId());
        // 拿出所有(去除本条)
        List<ApsBatch> apsBatchList = orderService.moveSchedule(reqVo);
        // 把本条插入最前面
        apsBatchList.add(0, source);
        // 清理排产数据
        apsOrderService.afterScheduleClear(apsBatchList);

        // 全部重新排产
        for (int i = 0; i < apsBatchList.size(); i++) {
            ApsBatch apsBatch = apsBatchList.get(i);

            OrderScheduleReqVo rrr = new OrderScheduleReqVo();
            rrr.setSchedulingRule(apsBatch.getSchedulingRule());
            List<ApsOrder> schedule = orderService.schedule(rrr, apsBatch);


            ApsOrderScheduleReqVo reqVo1 = new ApsOrderScheduleReqVo();
            reqVo1.setIds(schedule.stream().map(BaseEntity::getId).collect(Collectors.toList()));
            reqVo1.setSchedulingRule(rrr.getSchedulingRule());
            reqVo1.setStartDateTime(LocalDateTime.of(LocalDate.now().plusDays(1), LocalTime.of(0, 0, 0)));
            try {

                // 锁定
                apsOrderService.lock(reqVo1);

                // 清理订单
                apsOrderService.clear(reqVo1.getIds());

                // 排产
                apsOrderService.schedule(reqVo1, apsBatch);

                // 如果抛异常，则给未排产的解锁
                apsOrderService.unlock(reqVo1, 5);

            } catch (Exception e) {


                // 如果抛异常，则给未排产的解锁
                apsOrderService.unlock(reqVo1, 3);
                // 清理订单
                apsOrderService.clear(reqVo1.getIds());

                log.error(e.getMessage(), e);
                throw e;
            }
            orderService.publish();
        }


        return BaseResVo.ok();

    }

    @ApiOperation("工作组负荷工位树-王总")
    @GetMapping("/workLoadsTree")
    public BaseListResVo<OrderWorkLoadsTreeResVo> workLoadsTree() {
        return orderService.workLoadsTree();
    }

    @ApiOperation("工作组负荷柱状图-王总")
    @GetMapping("/workLoads")
    public BaseListResVo<OrderWorkLoadsResVo> workLoads(OrderWorkLoadsReqVo reqVo) {

        if (reqVo.getStartDate() == null || reqVo.getEndDate() == null) {
            throw SyExceptionUtils.e("请传入开始时间和结束时间");
        }

        if (reqVo.getEndDate().isBefore(reqVo.getStartDate())) {
            throw SyExceptionUtils.e("结束时间不能小于开始时间");
        }

        if (CollUtil.isEmpty(reqVo.getStationIds())) {
            throw SyExceptionUtils.e("请选择工位");
        }

        return orderService.workLoads(reqVo);
    }

    @ApiOperation("删除订单")
    @PostMapping("/delete")
    public BaseResVo delete(@RequestBody BaseIdReqVo reqVo) {
        orderService.delete(reqVo);
        return BaseResVo.ok();
    }


    @Deprecated
    @ApiOperation("订单重排")
    @PostMapping("/reorderTODOXXX")
    public BaseResVo reorder(@RequestBody OrderReorderReqVo reqVo2) {
        Map<ApsBatch, List<Order>> reorder = orderService.reorder(reqVo2);

        apsOrderService.reorder(reqVo2, reorder);

        return BaseResVo.ok();
    }

    @ControllerAspectIgnore
    @ApiOperation("下载订单同步的错误信息")
    @GetMapping("/syncError")
    public ResponseEntity<byte[]> syncError(OrderSyncErrorReqVo reqVo) throws Exception {
        try(Workbook workbook = orderService.syncError(reqVo)){
            String fileName = "错误信息" + reqVo.getConstructNo() + "-" + reqVo.getMaterCode() + ".xlsx";
            String fileNameEncoded = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            workbook.write(bytes);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentDisposition(ContentDisposition.builder("attachment").filename(fileNameEncoded).build());
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            return new ResponseEntity<>(bytes.toByteArray(), headers, HttpStatus.OK);
        }

    }

    @ApiOperation("获取订单的子包")
    @GetMapping("/subOrder")
    public BaseListResVo<OrderSubOrderResVo> subList(BaseIdReqVo reqVo){

        List<OrderSubOrderResVo> resVo = apsOrderService.subList(reqVo);

        return new BaseListResVo<>(resVo);
    }

    @ApiOperation("图纸推送详情")
    @GetMapping("/drawingPushDetail")
    public Result<PageUtils<OrderDrawingPushDetailResVo>> drawingPushDetail(OrderDrawingPushDetailReqVo reqVo) {
        List<OrderDrawingPushDetailResVo> list = orderService.drawingPushDetail(reqVo);
        PageUtils<OrderDrawingPushDetailResVo> page = new PageUtils<>(reqVo.getPage(), reqVo.getSize(), list);
        return Result.success(page);
    }

    @ApiOperation("计划推送详情")
    @GetMapping("/planPushDetail")
    public Result<PageUtils<OrderPlanPushDetailResVo>> planPushDetail(OrderPlanPushDetailReqVo reqVo) {
        List<OrderPlanPushDetailResVo> list = orderService.planPushDetail(reqVo);
        PageUtils<OrderPlanPushDetailResVo> page = new PageUtils<>(reqVo.getPage(), reqVo.getSize(), list);
        return Result.success(page);
    }

    @ApiOperation("推送回传详情")
    @GetMapping("/receiveDetail")
    public Result<PageUtils<OrderReceiveDetailResVo>> receiveDetail(OrderReceiveDetailReqVo reqVo) {
        List<OrderReceiveDetailResVo> list = orderService.receiveDetail(reqVo);
        PageUtils<OrderReceiveDetailResVo> page = new PageUtils<>(reqVo.getPage(), reqVo.getSize(), list);
        return Result.success(page);
    }

    @ApiOperation("推送状态")
    @GetMapping("/pushStatus")
    public BasePageResVo<OrderPushStatusResVo> pushStatus(OrderPushStatusReqVo reqVo) {
        return orderService.pushStatus(reqVo);
    }

    @ApiOperation("图纸推送状态")
    @GetMapping("/drawPushStatus")
    public BasePageResVo<OrderDrawPushStatusResVo> drawPushStatus(OrderDrawPushStatusReqVo reqVo) {
        return orderService.drawPushStatus(reqVo);
    }

    @ApiOperation("计划推送状态")
    @GetMapping("/planPushStatus")
    public BasePageResVo<OrderPlanPushStatusResVo> planPushStatus(OrderPlanPushStatusReqVo reqVo) {
        return orderService.planPushStatus(reqVo);
    }

    @ApiOperation("手动添加订单")
    @PostMapping("/addOrder")
    public BaseResVo addOrder(@RequestBody OrderAddReqVo reqVo) {
        orderService.addOrder(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("订单强制完成")
    @PostMapping("/finishOrder")
    public BaseResVo finishOrder(@RequestBody BaseIdReqVo reqVo) {
        orderService.finishOrder(reqVo);
        return BaseResVo.ok("操作成功");
    }

    @ApiOperation("订单追加")
    @PostMapping("/append")
    public BaseResVo append(@RequestBody OrderAppendReqVo reqVo) {
        orderService.append(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("搬——Frame——架型-从Erp导入模板（同步至标准架型）")
    @PostMapping("/orderErp")
    public BaseResVo orderErp(@RequestBody ImportFrameOrderPubReqVo reqVo){
        orderService.orderErp(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("搬——Frame——架型-从Erp导入模板（添加至标准架型）")
    @PostMapping("/orderErpAppend")
    public BaseResVo orderErpAppend(@RequestBody ImportFrameOrderErpAppendReqVo reqVo){
        orderService.orderErpAppend(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("搬——Frame——架型-发布到MBD")
    @PostMapping("/orderMbd")
    public BaseResVo orderMbd(@RequestBody ImportFrameOrderMbdReqVo reqVo) {
        orderService.orderMbd(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("订单拆分")
    @PostMapping("/split")
    public BaseResVo split(@RequestBody OrderSplitReqVo reqVo) {
        orderService.split(reqVo);
        return BaseResVo.ok();
    }

    @ControllerAspectIgnore
    @ApiOperation("订单Excel导入")
    @PostMapping("/importExcel")
    public BaseResVo importExcel(@RequestParam("file") MultipartFile file, @RequestParam("id") Integer orderId) throws IOException {
        File file1 = new File("/home/storage/order/import/excel/" + UUID.randomUUID() + "." + StringUtils.getFilenameExtension(file.getOriginalFilename()));
        FileUtils.copyToFile(file.getInputStream(), file1);
        orderService.importExcel(orderId, file1);
        return BaseResVo.ok();
    }

    @ApiOperation("订单-新增（新）")
    @PostMapping("/addOrderNew")
    public BaseResVo addOrderNew(@RequestBody OrderAddNewReqVo reqVo) {
        orderService.addOrderNew(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("订单-修改（新）")
    @PostMapping("/editOrderNew")
    public BaseResVo editOrderNew(@RequestBody OrderEditNewReqVo reqVo) {
        orderService.editOrderNew(reqVo);
        return BaseResVo.ok();
    }

}
